import sun.plugin.javascript.navig.JSObjectFactory
import java.util.Timer
import java.util.TimerTask

/**
 * author:vesper.z
 * date: 2024  17:35
 * class: Test05
 * description：类和对象
 * 可以包括构造函数和初始化代码、函数、属性、内部类、对象声明。
 **/
class Test05 {
    //类的属性
    var name: String = ""

    //类的方法
    fun test(): Int {

        return 1
    }
}


//如果主构造器没有任何的注解，也没有任何可见度修饰符，可以直接省略constructor关键字
class TestMain2(name: String, age: Int) {
    fun test() {
        println("省略了主构造器的constructor关键字！")
    }
}

/**
 * getter和setter
 * 属性完整的声明需要有getter和setter
 */
class GetterAndSetter {
    var name: String? = ""
        get() {
            return field //后端变量
        }//get方法
        set(value) {
            field = value
        }//set方法

    var age: Int? = 0
        get() {
            return field
        }
        set(value) {
            field = value
        }

    override fun toString(): String {
        return super.toString()
    }

    var address: String? = "浙江" //默认实现了getter和setter方法
    val hobby: String? = "lanqiu" //默认实现了getter方法

    //非空的属性必须在定义的时候初始化，如果想要延迟初始化需要使用lateinit关键字
    lateinit var testMain: TestMain2
    fun testLateInit() {
        testMain = TestMain2("vesper", 27)
        println(testMain.toString())
    }

    //
}

/**
 * 主构造器
 */
//主构造器
//构造器中的参数可以在初始化代码中使用，也可以在类主体n定义的属性初始化代码中使用。
//不需要类有公共的构造函数，使用private声明。
class Person private constructor(firstName: String) {
    init {
        println("Frist name is $firstName")
    }
}

/**
 * 次构造函数
 */
class TestMain constructor(name: String) {
    //类也可以有二级的构造函数，需要加前缀constructor，如下
    constructor(name: String, weight: Float, height: Float) : this(name) {

    }

    init {
        println("this name is $name")
    }

    fun test() {
        //创建一个类的实例
        var test05 = Test05()
        //直接通过名称引用它的属性
        test05.name = "zhangsan"
    }
}

/**
 * 抽象类
 */
open class Base {
    open fun f() {
    }
}

abstract class TestA : Base() {
    override fun f() {
        super.f()
    }

    abstract fun f1()
}

class TestB : TestA() {
    override fun f1() {
        println("this is TestB")
    }
}

/**
 * 嵌套类
 */
class Outter {//外部类
    private var arg: String = ""
    class Nested {//嵌套类
        fun foo(){ println("嵌套类") }
    }

}

/**
 * 内部类
 * 内部类使用inner关键字来表示
 */
class Outer1{
   inner class Inner{
        fun foo(){ println("内部类") }
    }
}

/**
 * 匿名内部类
 */
//使用对象表达式来创建匿名内部类
//定义接口
interface TestInterface{
    fun foo1()
    fun foo2()
}
class MyInterfaceTest{
    fun  addInterface(test:TestInterface){
      Timer().schedule(object: TimerTask() {
          override fun run() {
             test.foo1()
          }
      },5000)

        Timer().schedule(object: TimerTask() {
            override fun run() {
                test.foo2()
            }
        },10000)
    }
}

/**
 * 类的修饰符
 */
//类的修饰符包括classModifier和accessModifier
/**
 * classModifier:类属性修饰符，标示类本身特性
 *
 * abstract    // 抽象类
 * final       // 类不可继承，默认属性
 * enum        // 枚举类
 * open        // 类可继承，类默认是final的
 * annotation  // 注解类
 *
 */
/**
 * accessModifier: 访问权限修饰符
 *
 * private    // 仅在同一个文件中可见
 * protected  // 同一个文件中或子类可见
 * public     // 所有调用的地方都可见
 * internal   // 同一个模块中可见
 *
 */
fun main(args: Array<String>) {
    var myInterfaceTest = MyInterfaceTest()

    myInterfaceTest.addInterface(object:TestInterface{
        override fun foo1() {
            println("foo1")
        }

        override fun foo2() {
           println("foo2")
        }

    })

    var outer1 = Outer1()
    var inner = outer1.Inner()
    inner.foo()

    var nested = Outter.Nested()
    nested.foo()

    var testB = TestB()
    testB.f1()
    var getterAndSetter = GetterAndSetter()
    getterAndSetter.testLateInit()
}